package com.xinyue.game.client.network;

import com.xinyue.game.utils.encrypt.AESUtils;
import com.xinyue.game.utils.encrypt.RSAUtils;
import com.xinyue.network.codec.GameMessageContext;
import com.xinyue.network.hamdlermapping.GameChannelContext;
import com.xinyue.network.message.ChannelHandShakeRequest;
import com.xinyue.network.message.ChannelHandShakeResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Attribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;

import java.nio.charset.StandardCharsets;

/**
 * @Author 王广帅
 * @Date 2021/3/7 14:58
 */
public class ChannelHandShakeHandler extends ChannelInboundHandlerAdapter {
    private static Logger logger = LoggerFactory.getLogger(ChannelHandShakeHandler.class);
    private byte[] aesKey;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.info("连接创建成功");
        if (this.aesKey == null) {
            // 发送握手信息
            ChannelHandShakeRequest request = new ChannelHandShakeRequest();
            ctx.writeAndFlush(request);
        } else {
            ctx.fireChannelActive();
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.warn("连接已断开！");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof GameMessageContext) {
            GameMessageContext gameMessageContext = (GameMessageContext) msg;
            int messageId = gameMessageContext.getHeader().getMessageId();
            if (messageId == 1) {
                ChannelHandShakeResponse response = gameMessageContext.getGameMessage();
                if (response.getPubKey() != null) {
                    logger.debug("收到服务器公钥:{}", response.getPubKey());
                    byte[] rsaEncryptPublicKey = Base64Utils.decodeFromString(response.getPubKey());
                    //生成aes加密密钥
                    this.aesKey = AESUtils.createSecret().getBytes(StandardCharsets.UTF_8);
                    //加密传给服务器
                    byte[] encryptAesKey = RSAUtils.encryptByPublicKey(aesKey, rsaEncryptPublicKey);
                    String str = Base64Utils.encodeToString(encryptAesKey);
                    ChannelHandShakeRequest request = new ChannelHandShakeRequest();
                    request.setAesKey(str);
                    ctx.writeAndFlush(request);
                } else {
                    logger.debug("服务器接收加密密钥成功");
                    //后面的消息都使用对称加密密钥进行加密传输
                    Attribute<byte[]> attr = ctx.channel().attr(GameChannelContext.CHANNEL_AES_ENCRYPT_KEY);
                    attr.set(this.aesKey);
                }
                return;
            } else {
                ctx.fireChannelRead(msg);
            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }
}
